package com.example.cm_design

import android.animation.Animator
import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
import androidx.core.animation.addListener

/**
 * 音乐跳动View
 */
class SongWaveView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
    private var wave_color = 0
    private var wave_speed = 0
    private var waveWidth = dp2px(2)
    private var mSpace = dp2px(3)
    private var waveHeight = dp2px(13)
    private val mPaint: Paint by lazy {
        Paint().apply {
            isAntiAlias = true
            color = wave_color
        }
    }

    init {
        context.obtainStyledAttributes(attrs, R.styleable.SongWaveView).apply {
            wave_color = getColor(R.styleable.SongWaveView_wave_color, Color.parseColor("#FF5722"))
            wave_speed = getInteger(R.styleable.SongWaveView_wave_speed, 600)
            recycle()
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        var mWidth = MeasureSpec.getSize(widthMeasureSpec)
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        if (widthMode != MeasureSpec.EXACTLY) {
            mWidth = (3 * waveWidth + 2 * mSpace).toInt()
        }

        var mHeight = MeasureSpec.getSize(heightMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)

        if (heightMode != MeasureSpec.EXACTLY) {
            mHeight = waveHeight.toInt()
        }
        setMeasuredDimension(mWidth, mHeight)
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        waveWidth = (width - mSpace * 2) / 3f
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        val left = 0f
        val right = waveWidth
        val bottom = height.toFloat()
        canvas.drawRoundRect(
            left,
            (1 - changeTops[0]) * bottom,
            right,
            bottom,
            dp2px(10),
            dp2px(10),
            mPaint
        )

        canvas.drawRoundRect(
            left + waveWidth + mSpace,
            (1 - changeTops[1]) * bottom,
            right + waveWidth + mSpace,
            bottom,
            dp2px(10),
            dp2px(10),
            mPaint
        )

        canvas.drawRoundRect(
            width.toFloat() - waveWidth,
            (1 - changeTops[2]) * bottom,
            width.toFloat(),
            bottom,
            dp2px(10),
            dp2px(10),
            mPaint
        )
    }

    private var changeTops = arrayListOf(1f, 0.5f, 0.2f)
    private var anims = arrayListOf<Animator>()

    private val animatorSet: AnimatorSet by lazy {
        for (i in 0..2) {
            val anim = ValueAnimator.ofFloat(0.2f, 1f).apply {
                repeatMode = ValueAnimator.REVERSE
                repeatCount = ValueAnimator.INFINITE
                duration = wave_speed.toLong()
                addUpdateListener {
                    changeTops[i] = it.animatedValue as Float
                    invalidate()
                }
                addListener {
                    it.isRunning
                }
                startDelay = i * 200L
            }
            anims.add(anim)
        }

        AnimatorSet().apply {
            playTogether(anims)
        }
    }

    fun startAnimator(){
        animatorSet.start()
    }

    fun resumeAnimator(){
        animatorSet.resume()
    }

    fun pauseAnimator(){
        animatorSet.pause()
    }

    fun cancelAnimator(){
        animatorSet.cancel()
    }


    override fun toString(): String {
        return "${this.hashCode()}"
    }

    fun dp2px(dp: Int) = resources.displayMetrics.density * dp
}